<template>
  <div id="routeTopo" ref="routeTopo" style="width: 100%; height: 100%" />
</template>
<script>
  import { mapGetters } from 'vuex'
  import { Graph } from '@antv/x6'
  import jfImg from '@/assets/img/gis/jf-normal.png'
  import aoccImg from '@/assets/img/gis/aocc-normal.png'
  import getThemeColor from '@/utils/themesColor'
  import { deepClone } from '@/utils/common'

  export default {
    props: {
      routeList: {
        type: Array,
        default: () => []
      },
      activeRoute: {
        type: Object,
        default: () => {}
      }
    },
    data() {
      return {
        cableData: [],
        mapData: {},
        graph: null,
        viewX: 0,
        viewY: 0,
        viewList: [],
        colorData: {
          // 多主题颜色获取
          normal: getThemeColor('topoColor') || '#A2B1C3',
          damage: getThemeColor('topoDamage') || 'red',
          highLight: getThemeColor('topoHighLight') || '#E69318',
          alwaysHighLight: getThemeColor('alwaysHighLight') || '#12f10f'
        }
      }
    },
    computed: {
      ...mapGetters(['baseRegionList'])
    },
    watch: {
      routeList() {
        // 去重站点、光缆相同的链路
        const viewList = []
        const routeList = deepClone(this.routeList).reverse()
        routeList.forEach(i => {
          if (!viewList.some(j => j.segmentLinkId === i.segmentLinkId)) {
            viewList.push(i)
          }
        })
        this.viewList = viewList.map(i => i.segmentList)
        this.formatData()
      },
      activeRoute(newVal, oldVal) {
        this.hoverEdge(oldVal, 'leave')
      }
    },
    mounted() {
      this.createMap()
    },
    beforeDestroy() {
      this.graph.dispose()
    },
    methods: {
      formatData() {
        this.viewList.forEach((i, iIndex) => {
          i.forEach((j, jIndex) => {
            j.nodeX = iIndex === 0 || jIndex === 0 ? jIndex : jIndex - 1
            j.nodeY = Math.round(iIndex / 2) * Math.pow(-1, iIndex)
          })
        })
        this.renderMap()
      },
      renderMap() {
        const nodes = {}
        const edges = []
        const cableData = []
        this.graph.clearCells()
        if (!this.viewList.length) return
        // 光缆列表去重
        this.viewList.flat().forEach(i => {
          if (!cableData.some(j => j.cableId === i.cableId)) {
            cableData.push(i)
          }
        })
        console.log('this.cableData', cableData)
        const baseX = 100
        const offsetX = Math.min(
          Math.floor((this.viewX - 20) / this.viewList[this.viewList.length - 1].length),
          300
        )
        const baseY = Math.floor(this.viewY / 2)
        const offsetY = Math.floor((this.viewY - 20) / this.viewList.length)
        // 遍历列表，确定链接线起止id，链接点个数
        cableData.forEach(i => {
          const startNode = {
            stationId: i.startStationId,
            stationName: i.startStationName,
            x: baseX + i.nodeX * offsetX,
            y: baseY + i.nodeY * offsetY,
            portList: []
          }
          const endNode = {
            stationId: i.endStationId,
            stationName: i.endStationName,
            x: baseX + (i.nodeX + 1) * offsetX,
            y: baseY + i.nodeY * offsetY,
            portList: []
          }
          // 获取AZ相同的光缆
          const sameCable = cableData.filter(
            j =>
              (j.startStationId === i.startStationId && j.endStationId === i.endStationId) ||
              (j.startStationId === i.endStationId && j.endStationId === i.startStationId)
          )
          if (sameCable.length > 1) {
            const nodeY = sameCable[0].nodeY
            sameCable.forEach((j, jIndex) => {
              if (j.startStationId === i.endStationId && j.endStationId === i.startStationId) {
                j.startStationId = i.startStationId
                j.endStationId = i.endStationId
              }
              let startPosition = [0, 0]
              let endPosition = [0, 0]
              const offset = parseInt((40 / (sameCable.length + 1)) * (jIndex + 1))
              if (nodeY > 0) {
                startPosition = [offset, 0]
                endPosition = [offset, 40]
              } else if (nodeY < 0) {
                startPosition = [offset, 40]
                endPosition = [offset, 0]
              } else {
                console.log()
                startPosition = [40, offset]
                endPosition = [0, offset]
              }
              const startPort = {
                id: j.startStationId + '_' + j.cableId,
                x: startPosition[0],
                y: startPosition[1]
              }
              startNode.portList.push(startPort)
              const endPort = {
                id: j.endStationId + '_' + j.cableId,
                x: endPosition[0],
                y: endPosition[1]
              }
              endNode.portList.push(endPort)
            })
            // console.log(sameCable)
          }
          if (!nodes[i.startStationId]) {
            startNode.isAocc = this.getNodeType(i.startStationId)
            nodes[i.startStationId] = startNode
          } else if (startNode.portList.length) {
            const newList = startNode.portList.filter(
              j => !nodes[i.startStationId].portList.some(z => z.id === j.id)
            )
            nodes[i.startStationId].portList = [...nodes[i.startStationId].portList, ...newList]
          }
          if (!nodes[i.endStationId]) {
            endNode.isAocc = this.getNodeType(i.endStationId)
            nodes[i.endStationId] = endNode
          } else if (endNode.portList.length) {
            const newList = endNode.portList.filter(
              j => !nodes[i.endStationId].portList.some(z => z.id === j.id)
            )
            nodes[i.endStationId].portList = [...nodes[i.endStationId].portList, ...newList]
          }

          // 过滤自联站点
          if (i.startStationId !== i.endStationId) {
            edges.push(this.createEdge(i))
          }
        })
        console.log('nodes', nodes)
        this.addOverview(nodes, edges)
      },
      getNodeType(nodeId) {
        return this.routeList.some(i =>
          i.segmentList.some(
            j =>
              (j.startNodeId === nodeId && j.startNode.nodeType === 'AOCC') ||
              (j.endNodeId === nodeId && j.endNode.nodeType === 'AOCC')
          )
        )
      },
      addOverview(nodes, edges) {
        Object.keys(nodes).forEach(i => {
          const portList = nodes[i].portList
          const items = []
          if (portList) {
            portList.forEach(j => {
              items.push({
                id: j.id,
                group: 'group1',
                args: {
                  x: j.x,
                  y: j.y
                }
              })
            })
          }
          // console.log('startPortList', startPortList)

          const nodeItem = {
            ...nodes[i],
            items: items
          }
          this.graph.addNode(this.createNode(nodeItem))
        })
        edges.forEach(i => {
          this.graph.addEdge(i)
        })
      },
      createEdge(cableData) {
        return {
          id: cableData.cableId || cableData.startStationId + '_' + cableData.endStationId,
          source: {
            cell: cableData.startStationId,
            port: cableData.startStationId + '_' + cableData.cableId
          },
          target: {
            cell: cableData.endStationId,
            port: cableData.endStationId + '_' + cableData.cableId
          },
          label: cableData.cableId && cableData.cable ? cableData.cable.cableName : '',
          attrs: {
            line: {
              targetMarker: '',
              stroke: this.colorData.normal,
              strokeWidth: 2
            }
          }
        }
      },
      createNode(nodeItem) {
        return {
          shape: 'image',
          imageUrl: nodeItem.isAocc ? aoccImg : jfImg,
          id: nodeItem.stationId,
          x: nodeItem.x,
          y: nodeItem.y,
          width: 40,
          height: 40,
          attrs: {
            label: {
              text: nodeItem.stationName,
              fill: this.colorData.normal,
              fontSize: 14,
              x: 0,
              y: 30
            }
          },
          ports: {
            groups: {
              group1: {
                attrs: {
                  circle: {
                    r: 0
                  }
                },
                position: {
                  name: 'absolute'
                }
              }
            },
            items: nodeItem.items
          }
        }
      },
      createMap() {
        this.$nextTick(() => {
          const viewBox = document.getElementById('routeTopo')
          this.viewX = viewBox.offsetWidth
          this.viewY = viewBox.offsetHeight
          this.graph = new Graph({
            container: viewBox,
            panning: true,
            mousewheel: {
              enabled: true,
              minScale: 0.3,
              maxScale: 2
            },
            translating: {
              restrict: true
            }
          })
          this.formatData()
        })
      },
      highLight() {
        // console.log('data', this.activeRoute)
        if (!this.activeRoute) return
        this.activeRoute.segmentList.forEach(i => {
          const target = this.graph.getCellById(i.cableId)
          target && target.attr('line/stroke', this.colorData.alwaysHighLight)
        })
      },
      hoverEdge(data, type) {
        // console.log('data', data)
        if (!data) return
        const color = type === 'enter' ? this.colorData.highLight : this.colorData.normal
        data.segmentList.forEach(i => {
          const target = this.graph.getCellById(i.cableId)
          target && target.attr('line/stroke', color)
        })
        if (type !== 'enter') {
          this.highLight()
        }
      }
    }
  }
</script>
<style></style>
